STK就是SIMToolKit。
问题如图,STK一个case的输入框,不应该能输入+:
这个界面从哪来的?
实际上,我们插入SIM卡,手机就会显示SimToolKit,打开就能看到一些和运营商相关的菜单。换了不同的卡菜单也会变。所以大概可以猜到,SIM卡里写有一些配置文件,STK会解析这些文件。
项目原因,正好可以拿到一些配置文件,如图:
通过Smartstation把配置文件写到模拟SIM卡中,然后插卡交给STK读取处理这些信息。
阅读Java文件,找到出问题的case代码:
case 30021:
GetInput getinput21 = new GetInput("Enter 67#*+.digits, SMS default alphabet, Terminal to hide text, packing required, help information available,\"+\" can not input.",4,8);
getinput21.digitsOnly();
getinput21.noEcho();
getinput21.textString().packed();
getinput21.helpInformationAvailable(true);
super.pch.sendCommand(getinput21.toByteArray());
super.state = 0;
break;
从文件可以知道,输入框是个GetInput对象。
输入对象配置了digitsOnly
,noEcho
,packed
等属性。
怎么处理配置文件?
有了配置文件,插SIM卡到手机,STK会处理这些数据。
在OpenGrok上搜索代码,可以找到输入部分,在STK的packages/apps/Stk/src/com/android/stk/StkInputActivity.java
文件中。
下面看一下configInputDisplay方法,配置输入显示。
private void configInputDisplay() {
TextView numOfCharsView = (TextView) findViewById(R.id.num_of_chars);
TextView inTypeView = (TextView) findViewById(R.id.input_type);
int inTypeId = R.string.alphabet;
// set the prompt.
mPromptView.setText(mStkInput.text);
// Set input type (alphabet/digit) info close to the InText form.
if (mStkInput.digitOnly) {
mTextIn.setKeyListener(StkDigitsKeyListener.getInstance());
inTypeId = R.string.digits;
}
inTypeView.setText(inTypeId);
if (mStkInput.icon != null) {
setFeatureDrawable(Window.FEATURE_LEFT_ICON, new BitmapDrawable(
mStkInput.icon));
}
// Handle specific global and text attributes.
switch (mState) {
case STATE_TEXT:
int maxLen = mStkInput.maxLen;
int minLen = mStkInput.minLen;
mTextIn.setFilters(new InputFilter[] {new InputFilter.LengthFilter(
maxLen)});
// Set number of chars info.
String lengthLimit = String.valueOf(minLen);
if (maxLen != minLen) {
lengthLimit = minLen + " - " + maxLen;
}
numOfCharsView.setText(lengthLimit);
if (!mStkInput.echo) {
mTextIn.setInputType(InputType.TYPE_CLASS_NUMBER
| InputType.TYPE_NUMBER_VARIATION_PASSWORD);
}
// Set default text if present.
if (mStkInput.defaultText != null) {
mTextIn.setText(mStkInput.defaultText);
} else {
// make sure the text is cleared
mTextIn.setText("", BufferType.EDITABLE);
}
break;
case STATE_YES_NO:
// Set display mode - normal / yes-no layout
mYesNoLayout.setVisibility(View.VISIBLE);
mNormalLayout.setVisibility(View.GONE);
break;
}
}
代码中出现mStkInput.digitOnly
这样的判断,可以推断mStkInput
就是和配置文件里的GetInput
对象。
mStkInput
来自frameworks/opt/telephony/src/java/com/android/internal/telephony/cat/Input.java
定义如下:
Input() {
text = "";
defaultText = null;
icon = null;
minLen = 0;
maxLen = 1;
ucs2 = false;
packed = false;
digitOnly = false;
echo = false;
yesNo = false;
helpAvailable = false;
duration = null;
iconSelfExplanatory = false;
}
回到前面的class,因为STK file里有说明getinput21.digitsOnly();,所以会进入下面逻辑:
// Set input type (alphabet/digit) info close to the InText form.
if (mStkInput.digitOnly) {
mTextIn.setKeyListener(StkDigitsKeyListener.getInstance());
inTypeId = R.string.digits;
}
这里mTextIn是一个EditText,setKeyListener就是过滤字符的作用。
/**
* For entering dates in a text field.
*/
public class StkDigitsKeyListener extends NumberKeyListener {
@Override
protected char[] getAcceptedChars() {
return CHARACTERS;
}
public int getInputType() {
return EditorInfo.TYPE_CLASS_PHONE;
}
public static StkDigitsKeyListener getInstance() {
if (sInstance != null) {
return sInstance;
}
sInstance = new StkDigitsKeyListener();
return sInstance;
}
/**
* The characters that are used.
*
* @see KeyEvent#getMatch
* @see #getAcceptedChars
*/
public static final char[] CHARACTERS = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '#', '+'};
private static StkDigitsKeyListener sInstance;
}
可以看到,CHARACTERS
定义了可以输入的字符,其中包含’+’。如果不需要’+’,把这里的声明修改掉就OK
其实我也不做Tele,但通过这个过程,可以大概了解一些STK相关的原理。